package com.mallcloud.mall.common.core.util;

import com.alibaba.fastjson.JSONObject;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.Xpp3Driver;
import com.thoughtworks.xstream.io.xml.XppDriver;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.io.Writer;

/**
 * 对象与XML之间转化
 */
@UtilityClass
public class XmlParseUtil {

	/**
	 * @description Xml转Map
	 * @param str
	 * @return Map<String, Object>
	 */
	@SneakyThrows
	public static <T> T domParseWxXml(String str, Class<T> resClass) {
		StringReader read = null;
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			read = new StringReader(str);
			InputSource source = new InputSource(read);
			Document document = builder.parse(source);

			Element element = document.getDocumentElement();
			NodeList nodeList = element.getChildNodes();
			JSONObject map = new JSONObject();
			for (int i = 0; i < nodeList.getLength(); i++) {
				if (null != nodeList.item(i).getFirstChild()) {
					map.put(nodeList.item(i).getNodeName(), nodeList.item(i).getFirstChild().getNodeValue());
				}
			}
			return JSONObject.toJavaObject(map, resClass);
		} catch (Exception e) {
			throw new Exception("Xml转Map异常:" + e.getMessage(), e);
		} finally {
			read.close();
		}
	}
	/**
	 * @description 对象转xml
	 * @param obj 对象
	 * @param root 根节点
	 * @return
	 */
	public static String toXml(Object obj, String root) {
		XStream xstream = new XStream(new Xpp3Driver(new NoNameCoder()));
		xstream.alias(root, obj.getClass());
		return xstream.toXML(obj);
	}

	/**
	 * @description 对象转xml，并对对象值进行打包
	 * @param obj
	 * @param root
	 * @return
	 */
	public static String toPackagingXml(Object obj, String root, String packageFrom, String packageTo) {
		XStream xstream = new XStream(new XppDriver() {
			public HierarchicalStreamWriter createWriter(Writer out) {
				return new PrettyPrintWriter(out) {
					public void startNode(String name, Class clazz) {
						super.startNode(name, clazz);
					}
					protected void writeText(QuickWriter writer, String text) {
						writer.write(packageFrom);
						writer.write(text);
						writer.write(packageTo);
					}
				};
			}
		});
		xstream.alias(root, obj.getClass());
		return xstream.toXML(obj);
	}

	@SneakyThrows
	public static void main(String[] args) {
//		WxPay2UnifiedOrderResponseVO responseVO = new WxPay2UnifiedOrderResponseVO();
//		responseVO.setReturnCode("SUCCESS");
//		responseVO.setReturnMsg("SUCCESS");
//		String xml = toXml(responseVO, "xml");
//		System.out.println(xml);

//		String xmlStr = "<xml><return_code>SUCCESS</return_code><return_msg>SUCCESS</return_msg></xml>";
//		WxPay2UnifiedOrderResponseVO t = domParseWxXml(xmlStr, WxPay2UnifiedOrderResponseVO.class);
//		System.out.println(JSON.toJSONString(t));
//		System.out.println(new ObjectMapper().writeValueAsString(t));

//		Test test = new Test();
//		test.setId(0);
//		test.setStoreName("a");
////		System.out.println(toXml(test));
//
//		XStream xstream = new XStream();
//		xstream.alias("person", Test.class);
//		String xml = xstream.toXML(test);
////		System.out.println(xml);
//		System.out.println(toPackagingXml(test,"person","[","]"));
	}
}
